package com.tanhua.dubbo.api.impl.mongo;

import com.mongodb.client.result.UpdateResult;
import com.tanhua.domain.mongo.*;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.dubbo.api.mongo.PublishApi;
import com.tanhua.dubbo.utils.IdService;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

// 远程调用当前服务的超时时间：200秒
@Service(timeout = 200000)
public class PublishApiImpl implements PublishApi {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private IdService idService;

    @Override
    public void save(Publish publish) {
        // 如何发布动态?
        //1. 往动态表插入数据: db.quanzi_publish.insert()
        //publish.setId(ObjectId.get());
        publish.setCreated(System.currentTimeMillis());
        //设置pid，用于推荐系统推荐计算
        publish.setPid(idService.getNextId("quanzi_publish"));
        mongoTemplate.insert(publish);

        //2. 往相册表插入数据: db.quanzi_album_1.insert()
        Album album = new Album();
        album.setPublishId(publish.getId());
        album.setCreated(publish.getCreated());
        mongoTemplate.insert(album, "quanzi_album_" + publish.getUserId());

        //3. 查询登陆用户的好友: db.tanhua_users.find({userId:1})
        // 查询结果，如：20、4、10、57、23
        Query query = new Query(
                Criteria.where("userId").is(publish.getUserId())
        );
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);

        //4. 好友的时间线表插入数据
        //db.quanzi_time_line_20.insert()
        //db.quanzi_time_line_4.insert() ...
        if (!CollectionUtils.isEmpty(friendList)) {
            for (Friend friend : friendList) {
                // 获取登陆用户的好友id: 20、4、10、57、23
                Long friendId = friend.getFriendId();
                // 往好友的时间线表插入登陆用户发布的动态
                TimeLine timeLine = new TimeLine();
                timeLine.setUserId(publish.getUserId());
                timeLine.setPublishId(publish.getId());
                timeLine.setCreated(publish.getCreated());
                // 保存
                mongoTemplate.insert(timeLine, "quanzi_time_line_" + friendId);
            }
        }
    }

    @Override
    public PageResult findByTimeLine(Long userId, Integer page, Integer pagesize) {
        // 查询好友动态：db.quanzi_time_line_1.find().limit(10).skip(0).sort({created:-1})
        // 构造条件对象
        Query query = new Query();
        // 分页
        query.limit(pagesize).skip((page - 1) * pagesize);
        // 排序
        query.with(Sort.by(Sort.Order.desc("created")));
        // 查询当前页数据
        List<TimeLine> list = mongoTemplate.find(query, TimeLine.class, "quanzi_time_line_" + userId);
        // 统计
        long count = mongoTemplate.count(query, TimeLine.class, "quanzi_time_line_" + userId);
        // 定义返回的动态集合：List<Publish>
        List<Publish> publishList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            for (TimeLine timeLine : list) {
                if (timeLine.getPublishId() != null) {
                    // 根据动态id查询
                    Publish publish =
                            mongoTemplate.findById(timeLine.getPublishId(), Publish.class);
                    if (publish != null) {
                        publishList.add(publish);
                    }
                }
            }
        }

        return new PageResult(page, pagesize, (int) count, publishList);
    }

    @Override
    public PageResult queryRecommendPublishList(Long userId, Integer page, Integer pagesize) {
        // db.recommend_quanzi.find({userId:1})
        // 构造条件
        Query query = new Query(Criteria.where("userId").is(userId));
        // 设置分页
        query.limit(pagesize).skip((page - 1) * pagesize);
        // 查询推荐动态
        List<RecommendQuanzi> list = mongoTemplate.find(query, RecommendQuanzi.class);
        long count = mongoTemplate.count(query, RecommendQuanzi.class);

        //定义返回的动态集合：List<Publish>
        List<Publish> publishList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            for (RecommendQuanzi recommendQuanzi : list) {
                if (recommendQuanzi.getPublishId() != null) {
                    // 根据动态id查询
                    Publish publish =
                            mongoTemplate.findById(recommendQuanzi.getPublishId(), Publish.class);
                    if (publish != null) {
                        // 查询动态，只返回审核通过的动态，state=1
                        if (publish.getState() != null && publish.getState() == 1) {
                            publishList.add(publish);
                        }
                    }
                }
            }
        }
        return new PageResult(page, pagesize, (int) count, publishList);
    }

    @Override
    public PageResult findByAlbum(Long userId, int page, int pagesize) {
        Query query = new Query()
                .limit(pagesize).skip((page - 1) * pagesize)
                .with(Sort.by(Sort.Order.desc("created")));
        List<Album> albumList =
                mongoTemplate.find(query, Album.class, "quanzi_album_" + userId);
        long count = mongoTemplate.count(query, Album.class, "quanzi_album_" + userId);

        List<Publish> result = new ArrayList<>();
        if (albumList != null && albumList.size() > 0) {
            albumList.forEach(album -> {
                Publish publish =
                        mongoTemplate.findById(album.getPublishId(), Publish.class);
                if (publish != null) {
                    if (publish.getState() != null && publish.getState() == 1) {
                        result.add(publish);
                    }
                }
            });
        }
        return new PageResult(page, pagesize, (int) count, result);
    }

    @Override
    public Publish findById(String publishId) {
        return mongoTemplate.findById(new ObjectId(publishId), Publish.class);
    }

    @Override
    public PageResult findPublishList(Integer page, Integer pagesize, Long uid, String state) {
        Query query = new Query();
        if (uid == null) {
            if (state==null || state.equals("") || state.equals("''")) {
                query.limit(pagesize).skip((page - 1) * pagesize);
            }else {
                query.addCriteria(Criteria.where("state").is(Integer.parseInt(state)));
                query.limit(pagesize).skip((page - 1) * pagesize);
            }
        }else {
            query.addCriteria(Criteria.where("userId").is(uid));
            query.limit(pagesize).skip((page - 1) * pagesize);
        }

        List<Publish> publishList = mongoTemplate.find(query, Publish.class);
        long count = mongoTemplate.count(query, Publish.class);

        return new PageResult(page, pagesize, (int) count, publishList);
    }

    @Override
    public void updateById(String publishId, Integer state) {
        Query query = new Query(Criteria.where("id").is(new ObjectId(publishId)));
        Update update = new Update();
        update.set("state", state);
        mongoTemplate.updateFirst(query, update, Publish.class);
    }

    @Override
    public List<Publish> findByPids(List<Long> pidList) {
        Query query = new Query(
                Criteria.where("pid").in(pidList)
        );
        List<Publish> publishList = mongoTemplate.find(query, Publish.class);
        return publishList;
    }

    @Override
    public List<ObjectId> findByAlbum(Long userId) {
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")));
        List<Album> albumList =
                mongoTemplate.find(query, Album.class, "quanzi_album_" + userId);
        //long count = mongoTemplate.count(query, Album.class, "quanzi_album_" + userId);

        List<ObjectId> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(albumList)) {
            albumList.forEach(album -> {
                result.add(album.getPublishId());
            });
        }

        return result;
    }

    /**
     * 修改驳回动态
     * @param publishList
     */
    @Override
    public boolean PassState(String[] publishList) {
        Query query = new Query(Criteria.where("id").in(publishList));
        Update update = new Update();
        update.set("state",1);
        UpdateResult updateResult = mongoTemplate.updateMulti(query, update, Publish.class);

        return updateResult.wasAcknowledged();
    }

    /**
     * 拒绝
     * @param publishIdList
     */
    @Override
    public boolean RejectState(String[] publishIdList) {
        Query query = new Query(Criteria.where("id").in(publishIdList));
        Update update = new Update();
        update.set("state",2);
        UpdateResult updateResult = mongoTemplate.updateMulti(query, update, Publish.class);
        return updateResult.wasAcknowledged();
    }
}
